home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / DB_CLIPP / 0643B.ZIP / SAY2FILE.ASM < prev    next >
Assembly Source File  |  1987-04-17  |  9KB  |  215 lines

  1. ; Program ...: Say2File.ASM
  2. ; Author ....: Keith Mund
  3. ; Date ......: May 1, 1987
  4. ;
  5. ;----------------------------------------------------------------------------
  6. ; DOS equates
  7. ;
  8. DOSINT  EQU     21H             ; DOS functions interrupt.
  9. HANCREA EQU     3CH             ; Handle file create function (and open).
  10. HANCLOS EQU     3EH             ; Handle file close.
  11. HANWRIT EQU     40H             ; Handle file write.
  12. HANDUPL EQU     45H             ; Duplicate existing handle.
  13. HANFORC EQU     46H             ; Redirect handle.
  14. STDPRN  EQU     04H             ; Standard printer device file handle.
  15. ;
  16. ;----------------------------------------------------------------------------
  17. ; ASCII equates, function codes and status return codes, etc.
  18. ;
  19. LF      EQU     0AH             ; ASCII line feed.
  20. CR      EQU     0DH             ; ASCII carriage return.
  21. EOF     EQU     1AH             ; ASCII end of file.
  22. ;
  23. DO_CLOS EQU     'C'             ; Close and restore function.
  24. DO_OPEN EQU     'O'             ; Open and redirect function.
  25. ;
  26. CLOS_ER EQU     'C'             ; Error closing the file.
  27. DUPL_ER EQU     'D'             ; Handle duplication error.
  28. OPEN_ER EQU     'O'             ; Error opening the file.
  29. REDI_ER EQU     'R'             ; Redirection error.
  30. SUCCESS EQU     ' '             ; Successful operation.
  31. SYNT_ER EQU     'S'             ; Syntax error.
  32. ;
  33. TO_UP   EQU     011011111B      ; Upper case conversion mask.
  34. ;
  35. ;----------------------------------------------------------------------------
  36. ; Segment and offset definition.
  37. ;
  38. CSEG    SEGMENT PARA PUBLIC 'CODE'
  39. ;
  40.         ORG     0
  41. ;
  42.         ASSUME  CS:CSEG,DS:CSEG,ES:CSEG
  43. ;
  44. MAIN    PROC    FAR
  45. ;
  46.         JMP     START           ; Skip over the data area.
  47. ;
  48. ;----------------------------------------------------------------------------
  49. ; Constants and variables.
  50. ;
  51.         DB      CR
  52.         DB      'Say2File.BIN by Keith Mund',CR,LF
  53.         DB      'Copyright (C) 1987 Ashton-Tate',CR,LF,EOF
  54. ACTIVE  DB      0               ; Active/inactive flag.
  55. HANDLE  DW      ?               ; Spool file handle.
  56. OLD_PRN DW      ?               ; Old printer device file handle.
  57. CREOF   DB      CR,EOF          ; To append to spool file before close.
  58. ;
  59. ;----------------------------------------------------------------------------
  60. ; The actual routine starts here.
  61. ; Every return instruction returns to dBASE III PLUS and the code moves 
  62. ; forward in a straight line fashion for structure.
  63. ;
  64. START:  MOV     SI,BX           ; Pointer to variable passed from dBASE III PLUS.
  65. ;
  66. ;----------------------------------------------------------------------------
  67. ; Check to see if a variable was passed, see note below.
  68. ;
  69.         MOV     AX,DS           ; The data segment is non-zero when a 
  70.         OR      AX,AX           ; variable is passed from dBASE III PLUS.
  71.         JNZ     Q_CLOS          ; Continue if not zero,
  72.         RET                     ; or else return to dBASE III PLUS.
  73. ;
  74. ;----------------------------------------------------------------------------
  75. ; Check for a request for a close.
  76. ;
  77. Q_CLOS: MOV     AL,[SI]         ; Get the command character (byte 1).
  78.         AND     AL,TO_UP        ; Make uppercase.
  79.         CMP     AL,DO_CLOS      ; Close function requested?
  80.         JNE     Q_OPEN          ; If not, check for open.
  81. ;
  82. ;----------------------------------------------------------------------------
  83. ; Restore the original printer device and close the files.
  84. ;
  85. CLOSE:  MOV     AL,CS:ACTIVE    ; Is another redirection in effect?
  86.         OR      AL,AL
  87.         JNZ     CLOSE0          ; If not, continue with close,
  88. ;
  89.         MOV     AL,'A'          ;     or else return an activity error.
  90.         MOV     [SI],AL         ;     Store the status in the memory variable.
  91.         RET
  92. ;
  93. CLOSE0: MOV     AH,HANFORC      ; Make the standard printer device
  94.         MOV     BX,CS:OLD_PRN   ;     track the original handle from
  95.         MOV     CX,STDPRN       ;     before the redirection.
  96.         INT     DOSINT          ; Ignore any error.
  97. ;
  98.         MOV     AH,HANCLOS      ; Close the duplicate of the original 
  99.         MOV     BX,CS:OLD_PRN   ;     standard print device.
  100.         INT     DOSINT          ; Ignore any error.
  101. ;
  102. CLOSE1: MOV     AH,HANWRIT      ; Write a CR,EOF to the output file.
  103.         PUSH    DS              ; Save the data segment passed from dBASE.
  104.         PUSH    CS              ; Now make the DS point to the data in 
  105.         POP     DS              ;     this code segment.
  106.         MOV     BX,CS:HANDLE    ; This specifies the output file.
  107.         MOV     CX,2            ; Bytes to write.
  108.         MOV     DX,OFFSET CS:CREOF
  109.         INT     DOSINT          ; Write them.
  110.         POP     DS              ; Restore the original data segment.
  111. ;
  112. CLOSE2: MOV     AH,HANCLOS      ; Close the output file.
  113.         MOV     BX,CS:HANDLE
  114.         INT     DOSINT
  115.         JC      CLOSE3          ; If an error, jump to report it,
  116. ;
  117.         MOV     AL,SUCCESS      ;     or else, return no error.
  118.         JMP     CLOSE4
  119. ;
  120. CLOSE3: MOV     AL,CLOS_ER
  121. ;
  122. CLOSE4: MOV     [SI],AL         ; Store the status in the memory variable.
  123.         MOV     CS:ACTIVE,0     ; Redirection flag set to 'not in effect'.
  124.         RET
  125. ;
  126. ;----------------------------------------------------------------------------
  127. ; Check for a request to open a file and redirect the printer output.
  128. ;
  129. Q_OPEN: CMP     AL,DO_OPEN      ; Open function?
  130.         JE      OPEN
  131. ;
  132.         MOV     AL,SYNT_ER
  133.         MOV     [SI],AL         ; Store the status in the memory variable.
  134.         RET
  135. ;
  136. ;----------------------------------------------------------------------------
  137. ; Try to do the redirection request
  138. ;
  139. OPEN:   MOV     AL,CS:ACTIVE    ; Check for redirection already in effect.
  140.         OR      AL,AL
  141.         JZ      OPEN0           ; If not, continue with redirection,
  142. ;
  143.         MOV     AL,'A'          ; or else quit.
  144.         MOV     [SI],AL         ; Store the status in the memory variable.
  145.         RET
  146. ;
  147. OPEN0:    MOV     AH,HANDUPL      ; Duplicate the existing printer handle.
  148.         MOV     BX,STDPRN
  149.         INT     DOSINT
  150.         JNC     CREATE          ; If successful, create the new output file,
  151. ;
  152.         MOV     AL,DUPL_ER      ;     or else return an error.
  153.         MOV     [SI],AL         ; Store the status in the memory variable.
  154.         RET
  155.  
  156. ;----------------------------------------------------------------------------
  157. ; Create a new file for the printer output.
  158. ;
  159. CREATE: MOV     CS:OLD_PRN,AX   ; Save the old printer handle.
  160.         MOV     AH,HANCREA      ; Create the file now.
  161.         MOV     CX,0            ; No attributes set.
  162.         MOV     DX,SI           ; Filename begins character 2 only,
  163.         INC     DX              ;      which is located at...
  164.         INT     DOSINT  
  165. ;
  166.         JNC     REDIR
  167. ;
  168.         MOV     AH,HANCLOS      ; If there is an error, close the 
  169.         MOV     BX,CS:OLD_PRN   ;     duplicate of the original prn device.
  170.         INT     DOSINT          ; Ignore any close error.
  171.         MOV     AL,OPEN_ER
  172.         MOV     [SI],AL         ; Store the status in the memory variable.
  173.         RET
  174. ;
  175. REDIR:  MOV     CS:HANDLE,AX    ; Save the handle.
  176.         MOV     AH,HANFORC      ; Do the redirection.
  177.         MOV     BX,CS:HANDLE    ; The output file.
  178.         MOV     CX,STDPRN       ; The original printer.
  179.         INT     DOSINT
  180.         JNC     REDIR1
  181. ;
  182.         MOV     AH,HANCLOS      ; Attempt to close the duplicate of 
  183.         MOV     BX,CS:OLD_PRN   ;     the original prn.
  184.         INT     DOSINT          ; Ignore any error.
  185.         MOV     AH,HANCLOS      ; Attempt to close the printer
  186.         MOV     BX,CS:HANDLE    ;     redirection file.
  187.         INT     DOSINT          ; Ignore any error.
  188.         MOV     AL,REDI_ER
  189.         MOV     [SI],AL         ; Store the status in the memory variable.
  190.         RET
  191. ;
  192. REDIR1: MOV     CS:ACTIVE,-1    ; Active flag set true - redirection exists.
  193.         MOV     AL,SUCCESS
  194.         MOV     [SI],AL         ; Store the status in the memory variable.
  195.         RET
  196. ;
  197. ;----------------------------------------------------------------------------
  198. ;
  199. MAIN    ENDP
  200. CSEG    ENDS
  201.         END
  202. ;
  203. ;----------------------------------------------------------------------------
  204. ;                           *** Note ***
  205. ;
  206. ; This test is an attempt to check that the call to Say2File.BIN included a
  207. ; parameter.  Without one, Say2File.BIN could return a result to an unknown
  208. ; location.  Segment register DS = 0 seems to be true any time dBASE III
  209. ; PLUS calls a .BIN module and no variable is passed.  Since this is not
  210. ; documented, this apparent fact could change in any future release.  It
  211. ; is also possible that it may not always be a faithful test for the
  212. ; existence of a parameter.  
  213. ;
  214. ; I justify including this test in this module because it works.
  215.